#version 330




#if VERTEX_SHADER

in vec3 position;

uniform mat4 cameraMatrix;
uniform mat4 modelMatrix;

out vec3 v_pos;

void main() {
    v_pos = (modelMatrix * vec4(position, 1.0)).xyz;
    gl_Position = cameraMatrix * vec4(v_pos, 1.0);
}



#elif GEOMETRY_SHADER

layout(triangles) in;
layout(triangle_strip, max_vertices = 3) out;

in vec3 v_pos[];
out vec3 normal;
out vec3 pos;

void main() {
    vec3 a = v_pos[0].xyz;
    vec3 b = v_pos[1].xyz;
    vec3 c = v_pos[2].xyz;
    vec3 l1 = b - a;
    vec3 l2 = c - a;
    vec3 n = normalize(cross(l1, l2));

    gl_Position = gl_in[0].gl_Position;
    pos = a;
    normal = n;
    EmitVertex();
    gl_Position = gl_in[1].gl_Position;
    pos = b;
    normal = n;
    EmitVertex();
    gl_Position = gl_in[2].gl_Position;
    pos = c;
    normal = n;
    EmitVertex();
    EndPrimitive();
}



#elif FRAGMENT_SHADER

in vec3 pos;
in vec3 normal;
uniform vec3 color;

#define maxLightCount 16
struct PointLights {
    float data[7 * maxLightCount];
    int count;
};
struct Lights {
    float data[4 * maxLightCount];
    int count;
};
struct StraightLights {
    float data[7 * maxLightCount];
    int count;
};
uniform Lights lights;
uniform bool haslights = false;
uniform PointLights pointLights;
uniform bool haspointLights = false;
uniform StraightLights straightLights;
uniform bool hasstraightLights = false;
vec3 handleLights() {
    vec3 light = vec3(0, 0, 0);
    if (haslights) {
        for (int i=0; i<lights.count; i++) {
            int idx = i * 4;
            vec3 lightColor = vec3(lights.data[idx], lights.data[idx+1], lights.data[idx+2]);
            float strength = lights.data[idx+3];
            light = light + lightColor * strength;
        }
    }
    if (haspointLights) {
        for (int i=0; i<pointLights.count; i++) {
            int idx = i * 7;
            vec3 plightColor = vec3(pointLights.data[idx], pointLights.data[idx+1], pointLights.data[idx+2]);
            vec3 plightPos = vec3(pointLights.data[idx+3], pointLights.data[idx+4], pointLights.data[idx+5]);
            float strength = pointLights.data[idx+6];
            vec3 lightIn = normalize(plightPos - pos);
            light = light + plightColor * dot(lightIn, normal) * strength;
        }
    }
    if (hasstraightLights) {
        for (int i=0; i<straightLights.count; i++) {
            int idx = i * 7;
            vec3 slightColor = vec3(straightLights.data[idx], straightLights.data[idx+1], straightLights.data[idx+2]);
            vec3 slightDir = vec3(straightLights.data[idx+3], straightLights.data[idx+4], straightLights.data[idx+5]);
            slightDir = normalize(slightDir);
            float strength = straightLights.data[idx+6];
            light = light + slightColor * dot(slightDir, normal) * strength;
        }
    }
    return light;
}

void main() {
    vec3 light = handleLights();
    gl_FragColor = vec4(color * light, 1.0);
}




#endif
